package com.xiyou.week04;

import java.util.*;

/**
 * 355. 设计推特
 *
 * @ClassName：Twitter
 * @Author：西柚
 * @Date：2022/1/24 11:55 上午
 * @Versiion：1.0
 */
public class Twitter {

    // 用户ID和推文的对应关系
    private Map<Integer, Tweet> twitter;
    // 用户ID和他关注的用户列表的对应关系
    private Map<Integer, Set<Integer>> followings;
    // 全局使用的时间戳字段，用户每发布一条推特之前+1
    private static int timestamp = 0;
    // 合并K组推文使用的数据结构（可以在方法里创建使用），声明成全局变量非必需
    private static PriorityQueue<Tweet> maxHeap;

    /**
     * 推文类，是一个单链表（节点视角）
     */
    private class Tweet {
        // 推文ID
        private int id;
        // 发推文的时间戳
        private int timestamp;
        private Tweet next;

        public Tweet(int id, int timestamp) {
            this.id = id;
            this.timestamp = timestamp;
        }
    }

    public Twitter() {
        followings = new HashMap<Integer, Set<Integer>>();
        twitter = new HashMap<Integer, Tweet>();
        maxHeap = new PriorityQueue<Tweet>();
    }

    public void postTweet(int userId, int tweetId) {
        timestamp++;
        if (twitter.containsKey(userId)) {
            Tweet oldHead = twitter.get(userId);
            Tweet newHead = new Tweet(tweetId, timestamp);
            newHead.next = oldHead;
            twitter.put(userId, newHead);
        } else {
            twitter.put(userId, new Tweet(tweetId, timestamp));
        }
    }

    public List<Integer> getNewsFeed(int userId) {
        // 由于全局使用，使用之前需要清空
        maxHeap.clear();

        // 如果自己发了推文也要算上
        if (twitter.containsKey(userId)) {
            maxHeap.offer(twitter.get(userId));
        }

        Set<Integer> followList = followings.get(userId);
        if (followList != null && followList.size() > 0) {
            for (Integer followingId : followList) {
                Tweet tweet = twitter.get(followingId);
                if (tweet != null) {
                    maxHeap.offer(tweet);
                }
            }
        }

        List<Integer> res = new ArrayList<Integer>(10);
        int count = 0;
        while (!maxHeap.isEmpty() && count < 10) {
            Tweet head = maxHeap.poll();
            res.add(head.id);

            if (head.next != null) {
                maxHeap.offer(head.next);
            }
            count++;
        }
        return res;
    }

    /**
     * @param followerId 发起关注者id
     * @param followeeId 被关注者id
     */
    public void follow(int followerId, int followeeId) {
        // 被关注的不能是自己
        if (followeeId == followerId) {
            return;
        }

        // 获取我自己关注的列表
        Set<Integer> followingList = followings.get(followerId);
        if (followingList == null) {
            Set<Integer> init = new HashSet<Integer>();
            init.add(followeeId);
            followings.put(followerId, init);
        } else {
            if (followingList.contains(followeeId)) {
                return;
            }
            followingList.add(followeeId);
        }
    }

    /**
     * @param followerId 发起关注者id
     * @param followeeId 被关注者id
     */
    public void unfollow(int followerId, int followeeId) {
        if (followeeId == followerId) {
            return;
        }

        // 获取我自己的关注列表
        Set<Integer> followingList = followings.get(followerId);

        if (followingList == null) {
            return;
        }

        followingList.remove(followeeId);
    }

    public static void main(String[] args) {
        Twitter twitter = new Twitter();
        twitter.postTweet(1, 1);
        List<Integer> res1 = twitter.getNewsFeed(1);
        System.out.println(res1);

        twitter.follow(2, 1);

        List<Integer> res2 = twitter.getNewsFeed(2);
        System.out.println(res2);

        twitter.unfollow(2, 1);

        List<Integer> res3 = twitter.getNewsFeed(2);
        System.out.println(res3);
    }
}
